#include "../mqserver/mq_message.hpp"
#include <gtest/gtest.h>
#include <string>

mqserver::MessageManagerPtr msgmp;
const std::string qname = "queue1";

class MessageTest : public testing::Environment 
{
public:
    virtual void SetUp() override { 
        msgmp = std::make_shared<mqserver::MessageManager>("./data/message");
        msgmp->initMessageQueue(qname);
    }
    virtual void TearDown() override {
        msgmp->clear();
        std::cout << "clear finish!\n";
    }
};

// 新增消息测试: 新增消息，然后测试可获取消息数量，以及持久化消息数量是否预期一致
TEST(message_test, insert_test)
{
    proto::message::BasicProperties bp;
    bp.set_id(helper::UUIDHelper::uuid());
    bp.set_delivery_mode(proto::message::DeliveryMode::DURABLE);
    bp.set_routing_key("news.sport.basketball");

    msgmp->insert(qname, &bp, "this is message[1]", proto::message::DeliveryMode::DURABLE);
    msgmp->insert(qname, nullptr, "this is message[2]", proto::message::DeliveryMode::DURABLE);
    msgmp->insert(qname, nullptr, "this is message[3]", proto::message::DeliveryMode::DURABLE);
    msgmp->insert(qname, nullptr, "this is message[4]", proto::message::DeliveryMode::DURABLE);
    msgmp->insert(qname, nullptr, "this is message[5]", proto::message::DeliveryMode::UNDURABLE);

    ASSERT_EQ(msgmp->pendingPushCount(qname), 5);
    ASSERT_EQ(msgmp->pendingAckCount(qname), 0);
    ASSERT_EQ(msgmp->durableCount(qname), 4);       // 持久化数量
    ASSERT_EQ(msgmp->totalCount(qname), 4);         // 持久化数量
}

// 获取消息测试：测试可获取消息数量，待确认消息数量，以及消息获取的顺序 
// TEST(message_test, select_test)
// {
//     ASSERT_EQ(msgmp->pendingPushCount(qname), 5);

//     mqserver::MessagePtr msg = msgmp->front(qname);
//     ASSERT_NE(msg, nullptr);
//     ASSERT_EQ(msg->payload().body(), std::string("this is message[1]"));
//     ASSERT_EQ(msgmp->pendingPushCount(qname), 4);
//     ASSERT_EQ(msgmp->pendingAckCount(qname), 1);

//     mqserver::MessagePtr msg2 = msgmp->front(qname);
//     ASSERT_NE(msg2, nullptr);
//     ASSERT_EQ(msg2->payload().body(), std::string("this is message[2]"));
//     ASSERT_EQ(msgmp->pendingPushCount(qname), 3);
//     ASSERT_EQ(msgmp->pendingAckCount(qname), 2);

//     mqserver::MessagePtr msg3 = msgmp->front(qname);
//     ASSERT_NE(msg3, nullptr);
//     ASSERT_EQ(msg3->payload().body(), std::string("this is message[3]"));
//     ASSERT_EQ(msgmp->pendingPushCount(qname), 2);
//     ASSERT_EQ(msgmp->pendingAckCount(qname), 3);

//     mqserver::MessagePtr msg4 = msgmp->front(qname);
//     ASSERT_NE(msg4, nullptr);
//     ASSERT_EQ(msg4->payload().body(), std::string("this is message[4]"));
//     ASSERT_EQ(msgmp->pendingPushCount(qname), 1);
//     ASSERT_EQ(msgmp->pendingAckCount(qname), 4);

//     mqserver::MessagePtr msg5 = msgmp->front(qname);
//     ASSERT_NE(msg5, nullptr);
//     ASSERT_EQ(msg5->payload().body(), std::string("this is message[5]"));
//     ASSERT_EQ(msgmp->pendingPushCount(qname), 0);
//     ASSERT_EQ(msgmp->pendingAckCount(qname), 5);
// }

// 删除消息测试: ack一条消息, 然后查看持久化消息数量，待确认消息数量
// TEST(message_test, delete_test)
// {
//     // 检查数据是否正常
//     ASSERT_EQ(msgmp->pendingPushCount(qname), 5);
//     mqserver::MessagePtr msg = msgmp->front(qname);
//     ASSERT_NE(msg, nullptr);
//     ASSERT_EQ(msg->payload().body(), std::string("this is message[1]"));
//     ASSERT_EQ(msgmp->pendingPushCount(qname), 4);
//     ASSERT_EQ(msgmp->pendingAckCount(qname), 1);
//     ASSERT_EQ(msgmp->durableCount(qname), 4);

//     // 应答删除
//     msgmp->ack("queue1", msg->payload().properties().id());
//     ASSERT_EQ(msgmp->pendingAckCount(qname), 0);
//     ASSERT_EQ(msgmp->durableCount(qname), 3);
//     ASSERT_EQ(msgmp->totalCount("queue1"), 4);
// }

// 销毁测试
// TEST(message_test, destory_test)
// {
//     msgmp->destoryMessageQueue(qname);
// }

// // 测试恢复数据
mqserver::MessageManagerPtr msgmp2;
class MessageTest2 : public testing::Environment 
{
public:
    virtual void SetUp() override { 
        msgmp2 = std::make_shared<mqserver::MessageManager>("./data/message");
    }
    virtual void TearDown() override {
        // bmp->clear();
        std::cout << "clear finish!\n";
    }
};
// insert之后, 启动另一个对象初始化qname, 测试恢复
TEST(message_test, select_recovery_test)
{
    msgmp2->initMessageQueue(qname);
    ASSERT_EQ(msgmp2->pendingPushCount(qname), 4);

    mqserver::MessagePtr msg = msgmp2->front(qname);
    ASSERT_NE(msg, nullptr);
    ASSERT_EQ(msg->payload().body(), std::string("this is message[1]"));
    ASSERT_EQ(msgmp2->pendingPushCount(qname), 3);
    ASSERT_EQ(msgmp2->pendingAckCount(qname), 1);

    mqserver::MessagePtr msg2 = msgmp2->front(qname);
    ASSERT_NE(msg2, nullptr);
    ASSERT_EQ(msg2->payload().body(), std::string("this is message[2]"));
    ASSERT_EQ(msgmp2->pendingPushCount(qname), 2);
    ASSERT_EQ(msgmp2->pendingAckCount(qname), 2);

    mqserver::MessagePtr msg3 = msgmp2->front(qname);
    ASSERT_NE(msg3, nullptr);
    ASSERT_EQ(msg3->payload().body(), std::string("this is message[3]"));
    ASSERT_EQ(msgmp2->pendingPushCount(qname), 1);
    ASSERT_EQ(msgmp2->pendingAckCount(qname), 3);

    mqserver::MessagePtr msg4 = msgmp2->front(qname);
    ASSERT_NE(msg4, nullptr);
    ASSERT_EQ(msg4->payload().body(), std::string("this is message[4]"));
    ASSERT_EQ(msgmp2->pendingPushCount(qname), 0);
    ASSERT_EQ(msgmp2->pendingAckCount(qname), 4);

    mqserver::MessagePtr msg5 = msgmp2->front(qname);
    ASSERT_EQ(msg5, nullptr);
}

int main(int argc,char *argv[])
{
    testing::InitGoogleTest(&argc, argv);
    testing::AddGlobalTestEnvironment(new MessageTest());
    testing::AddGlobalTestEnvironment(new MessageTest2());
    (void)(RUN_ALL_TESTS());
    return 0;
}
